﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace THO7AlgoritmTimerApplication {
    class MedianAlgorithm2 : VisionAlgorithm {
        private int mask;
        public MedianAlgorithm2(String name)
            : base(name) {
        }
        public override Bitmap DoAlgorithm(Bitmap sourceImage) {
            mask = getMarge();
            Bitmap dest = new Bitmap(sourceImage.Width, sourceImage.Height);
            BitmapData bmpdata = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            BitmapData bmpdata1 = dest.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            IntPtr ptr = bmpdata.Scan0;
            IntPtr ptr1 = bmpdata1.Scan0;
            int regellengte = Math.Abs(bmpdata.Stride);
            int bytes = regellengte * sourceImage.Height;
            byte[] rgbValues = new byte[bytes];
            byte[] output = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

            byte red_waarde = 0;
            byte blue_waarde = 0;
            byte green_waarde = 0;
            for (int regelnummer = 0; regelnummer < sourceImage.Height - ((mask / 2) + 1) * 2; regelnummer++) {
                for (int convolutie = 0; convolutie < regellengte - ((mask / 2) + 1) * 6; convolutie += 3) {
                    int begin_pixel = ((regelnummer * regellengte) + convolutie);
                    int[] red_hist = new int[256];
                    int[] blue_hist = new int[256];
                    int[] green_hist = new int[256];
                    for (int hoogte = 0; hoogte < mask; hoogte++) {
                        for (int breedte = 0; breedte < mask; breedte++) {
                            int pixel = begin_pixel + (hoogte * regellengte) + (breedte * 3);
                            blue_hist[rgbValues[pixel]]++;
                            green_hist[rgbValues[++pixel]]++;
                            red_hist[rgbValues[++pixel]]++;
                        }
                    }
                    int hist_mask = (((mask * mask) / 2) + 1);
                    for (byte i = 1; i < 255; i++) {
                        red_hist[i] += red_hist[i - 1];
                        if (red_hist[i] > hist_mask) {
                            red_waarde = i;
                            break;
                        }
                    }
                    for (byte i = 1; i < 255; i++) {
                        green_hist[i] += green_hist[i - 1];
                        if (green_hist[i] > hist_mask) {
                            green_waarde = i;
                            break;
                        }
                    }
                    for (byte i = 1; i < 255; i++) {
                        blue_hist[i] += blue_hist[i - 1];
                        if (blue_hist[i] > hist_mask) {
                            blue_waarde = i;
                            break;
                        }
                    }
                    output[begin_pixel + (regellengte * ((mask / 2) + 1)) + (((mask / 2) + 1) * 3)] = (blue_waarde);
                    output[begin_pixel + 1 + (regellengte * ((mask / 2) + 1)) + (((mask / 2) + 1) * 3)] = (green_waarde);
                    output[begin_pixel + 2 + (regellengte * ((mask / 2) + 1)) + (((mask / 2) + 1) * 3)] = (red_waarde);
                }
            }
            System.Runtime.InteropServices.Marshal.Copy(output, 0, ptr1, bytes);
            sourceImage.UnlockBits(bmpdata);
            dest.UnlockBits(bmpdata1);
            return dest;
        }
    }
}
